home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / dev.c.exabyte < prev    next >
Encoding:
Text File  |  1992-10-26  |  13.3 KB  |  672 lines

  1. /* 
  2.  * dev.c--
  3.  *
  4.  *    Device-dependent manipulations
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "What a depressingly stupid machine"
  17.  *      -- Marvin in _A Hitchiker's Guide to the Galaxy_
  18.  *
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/dev.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <sys/mtio.h>
  28. #include <sys/changer.h>
  29. #include <sys/ioctl.h>
  30. #include <sys/devio.h>
  31. #include "jaquith.h"
  32.  
  33. typedef struct mtop Dev_TapeCommand;
  34.  
  35. static char printBuf[T_MAXSTRINGLEN];
  36. extern int syserr;
  37.  
  38. #define EXB120_MAXBIN 115
  39. #define EXB120_MAXMSG 60
  40.  
  41.  
  42. /*
  43.  *----------------------------------------------------------------------
  44.  *
  45.  * Dev_MoveVolume --
  46.  *
  47.  *    Move a volume from source slot to destination slot in jukebox
  48.  *
  49.  * Results:
  50.  *    Ptr to block of specified size or NULL;
  51.  *
  52.  * Side effects:
  53.  *    Moves robot arm. May also affect volume reader.
  54.  *
  55.  * Note:
  56.  *      The tape reader devices in the EXB-120 jukebox are given slot
  57.  *      numbers 116-119. If one of these is the destination address
  58.  *      a tape load is effectively done.  
  59.  *
  60.  *----------------------------------------------------------------------
  61.  */
  62.  
  63. int
  64. Dev_MoveVolume(robotStream, src, dest)
  65.     int robotStream;          /* robot file descriptor */
  66.     int src;                  /* source location */
  67.     int dest;                 /* destination location */
  68. {
  69.     robot_params robotCmd;
  70.  
  71.     robotCmd.sourceAddr = src;
  72.     robotCmd.destAddr = dest;
  73.  
  74.     if (ioctl(robotStream, SCSI_MOVE_MEDIUM, (char *) &robotCmd) < 0) {
  75.     syserr = errno;
  76.     return T_ROBOTFAILED;
  77.     } else {
  78.         return T_SUCCESS;
  79.     }
  80.  
  81. }
  82.  
  83.  
  84.  
  85. /*
  86.  *----------------------------------------------------------------------
  87.  *
  88.  * Dev_OpenVolume --
  89.  *
  90.  *    Open the device
  91.  *
  92.  * Results:
  93.  *    return code
  94.  *
  95.  * Side effects:
  96.  *    None.
  97.  *
  98.  *----------------------------------------------------------------------
  99.  */
  100.  
  101. int
  102. Dev_OpenVolume(devName, flags)
  103.     char *devName;            /* name of device */
  104.     int flags;                /* read, write etc. flags */
  105. {
  106.     int fd;
  107.  
  108.     if ((fd=open(devName, flags, 0)) == -1) {
  109.     syserr = errno;
  110.     }
  111.     return fd;
  112. }
  113.  
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * Dev_CloseVolume --
  119.  *
  120.  *    Close the device
  121.  *
  122.  * Results:
  123.  *    return code
  124.  *
  125.  * Side effects:
  126.  *    None.
  127.  *
  128.  *----------------------------------------------------------------------
  129.  */
  130.  
  131. int
  132. Dev_CloseVolume(stream)
  133.     int stream;               /* file descriptor */
  134. {
  135.     if (close(stream) == -1) {
  136.     syserr = errno;
  137.     return T_FAILURE;
  138.     } else {
  139.     return T_SUCCESS;
  140.     }
  141. }
  142.  
  143.  
  144. /*
  145.  *----------------------------------------------------------------------
  146.  *
  147.  * Dev_ReadVolume --
  148.  *
  149.  *    Perform read operation on volume.
  150.  *
  151.  * Results:
  152.  *    return code
  153.  *
  154.  * Side effects:
  155.  *    None.
  156.  *
  157.  *----------------------------------------------------------------------
  158.  */
  159.  
  160. int
  161. Dev_ReadVolume(volStream, buf, bufSize)
  162.     int volStream;
  163.     char *buf;
  164.     int bufSize;
  165. {
  166.     int cnt;
  167.  
  168.     if ((cnt=read(volStream, buf, bufSize)) < 0) {
  169.     syserr = errno;
  170.     }
  171.     return cnt;
  172. }
  173.  
  174.  
  175. /*
  176.  *----------------------------------------------------------------------
  177.  *
  178.  * Dev_WriteVolume --
  179.  *
  180.  *    Perform write operation on volume.
  181.  *
  182.  * Results:
  183.  *    return code
  184.  *
  185.  * Side effects:
  186.  *    None.
  187.  *
  188.  *----------------------------------------------------------------------
  189.  */
  190.  
  191. int
  192. Dev_WriteVolume(volStream, buf, bufSize)
  193.     int volStream;
  194.     char *buf;
  195.     int bufSize;
  196. {
  197.     int cnt;
  198.  
  199.     if ((cnt=write(volStream, buf, bufSize)) < 0) {
  200.     syserr = errno;
  201.     }
  202.     return cnt;
  203. }
  204.  
  205.  
  206. /*
  207.  *----------------------------------------------------------------------
  208.  *
  209.  * Dev_UnloadVolume --
  210.  *
  211.  *    Open the pod bay door. I'm sorry I can't do that Dave.
  212.  *
  213.  * Results:
  214.  *    return code
  215.  *
  216.  * Side effects:
  217.  *    Rewinds and unloads tape. Moves robot arm.
  218.  *
  219.  *----------------------------------------------------------------------
  220.  */
  221.  
  222. int
  223. Dev_UnloadVolume(devName)
  224.     char *devName;            /* device name */
  225. {
  226.     int volStream;
  227.     Dev_TapeCommand tapeCmd;
  228.  
  229.     if ((volStream=open(devName, O_RDONLY, 0)) < 0) {
  230.     syserr = errno;
  231.     return T_FAILURE;
  232.     }
  233.     
  234.     tapeCmd.mt_op = MTOFFL;
  235.     tapeCmd.mt_count = 1;
  236.  
  237.     if (ioctl(volStream, MTIOCTOP, (char *)&tapeCmd) != 0) {
  238.     syserr = errno;
  239.         close(volStream);
  240.     return T_FAILURE;
  241.     }
  242.     close(volStream);
  243.  
  244.     return T_SUCCESS;
  245.  
  246. }
  247.  
  248. /*
  249.  *----------------------------------------------------------------------
  250.  *
  251.  * Dev_InitRobot --
  252.  *
  253.  *    Initialize robot.
  254.  *
  255.  * Results:
  256.  *    return code
  257.  *
  258.  * Side effects:
  259.  *    Instructs robot to build database of volume id's
  260.  *      using barcode reader.
  261.  *
  262.  * Note:
  263.  *      At the moment 'initialization' this means taking 
  264.  *      tape inventory.
  265.  *      
  266.  *----------------------------------------------------------------------
  267.  */
  268.  
  269. int
  270. Dev_InitRobot(robotName, robotStreamPtr)
  271.     char *robotName;          /* robot device name */
  272.     int *robotStreamPtr;      /* robot descriptor */
  273. {
  274.  
  275.     if ((*robotStreamPtr=open(robotName, O_RDWR)) < 0) {
  276.     syserr = errno;
  277.     return T_FAILURE;
  278.     } else {
  279.     return T_SUCCESS;
  280.     }
  281.  
  282. }
  283.  
  284.  
  285. /*
  286.  *----------------------------------------------------------------------
  287.  *
  288.  * Dev_ReadVolLabel --
  289.  *
  290.  *    Read volume label with barcode reader
  291.  *
  292.  * Results:
  293.  *    return code
  294.  *
  295.  * Side effects:
  296.  *    Instructs robot to return element status from its database.
  297.  *
  298.  *----------------------------------------------------------------------
  299.  */
  300.  
  301. int
  302. Dev_ReadVolLabel(robotStream, location, volLabel)
  303.     int robotStream;          /* robot descriptor */
  304.     int location;             /* home slot in jukebox */
  305.     char *volLabel;           /* receiving space for volume label */
  306. {
  307.  
  308.     syserr = EINVAL;
  309.     return T_FAILURE;
  310.  
  311. }
  312.  
  313.  
  314. /*
  315.  *----------------------------------------------------------------------
  316.  *
  317.  * Dev_CvtVolLabel --
  318.  *
  319.  *    Convert character volume label to unique integer.
  320.  *
  321.  * Results:
  322.  *    return code
  323.  *
  324.  * Side effects:
  325.  *    None.
  326.  *
  327.  * Note:
  328.  *      For present purposes, labels are of the form "<text><number>"
  329.  *
  330.  *----------------------------------------------------------------------
  331.  */
  332.  
  333. int
  334. Dev_CvtVolLabel(volLabel)
  335.     char *volLabel;
  336. {
  337.     int volId;
  338.     char *workPtr = volLabel+strlen(volLabel)-1;
  339.  
  340.     while ((workPtr >= volLabel) && (isdigit(*workPtr))) {
  341.     workPtr--;
  342.     }
  343.     if ((workPtr >= volLabel) && (sscanf(workPtr+1, "%d", &volId) == 1)) {
  344.     return volId;
  345.     } else {
  346.     return -1;
  347.     }
  348. }
  349.  
  350.  
  351.  
  352.  
  353. /*
  354.  *----------------------------------------------------------------------
  355.  *
  356.  * Dev_SeekVolume --
  357.  *
  358.  *    Seek to file marker
  359.  *
  360.  * Results:
  361.  *    return code
  362.  *
  363.  * Side effects:
  364.  *    Instructs tape to seek
  365.  *
  366.  *----------------------------------------------------------------------
  367.  */
  368.  
  369. int
  370. Dev_SeekVolume(volStream, blkId, absolute)
  371.     int volStream;            /* volume descriptor */
  372.     int blkId;                /* logical file num */
  373.     int absolute;             /* absolute positioning flag */
  374. {
  375.     int status;
  376.     Dev_TapeCommand tapeCmd;
  377.     int oldOffset = 0;
  378.     int retryCnt;   
  379.  
  380.     if ((blkId < 0) || (blkId > 10000)) {
  381.     fprintf(stderr,"Dev_SeekVolume: Bad blkId: %d\n", blkId);
  382.     }
  383.  
  384.     if ((volStream < 0) || (volStream > 20)) {
  385.     fprintf(stderr,"Dev_SeekVolume: Bad volStream: %d\n", volStream);
  386.     }
  387.  
  388.     if (absolute) {
  389.     tapeCmd.mt_op = MTREW;
  390.     tapeCmd.mt_count = 1;
  391.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  392.     while ((retryCnt++ < 5) && (status != 0)) {
  393.         fprintf(stderr, "Rewind failed: errno %d. Retrying...\n",
  394.             errno);
  395.         sleep(2);
  396.         status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  397.     }
  398.     if (status != 0) {
  399.         syserr = errno;
  400.         fprintf(stderr, "Couldn't rewind tape. errno %d\n",syserr);
  401.         return T_IOFAILED;
  402.     }
  403.     }
  404.  
  405.     if (blkId > 0) {
  406.     tapeCmd.mt_op = MTFSF;
  407.     tapeCmd.mt_count = blkId;
  408.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  409.     if (status != 0) {
  410.         syserr = errno;
  411.         fprintf(stderr, "Couldn't skip %d files: %d\n",
  412.             blkId, syserr);
  413.         return T_IOFAILED;
  414.     }
  415.     }
  416.  
  417.     return T_SUCCESS;
  418. }
  419.  
  420.  
  421.  
  422. /*
  423.  *----------------------------------------------------------------------
  424.  *
  425.  * Dev_WriteEOF --
  426.  *
  427.  *    write out EOF
  428.  *
  429.  * Results:
  430.  *    return code
  431.  *
  432.  * Side effects:
  433.  *    Puts file marker on tape
  434.  *
  435.  *----------------------------------------------------------------------
  436.  */
  437.  
  438. int
  439. Dev_WriteEOF(volStream, count)
  440.     int volStream;            /* active stream */
  441.     int count;                /* number of marks to write */
  442. {
  443.     int status;
  444.     Dev_TapeCommand tapeCmd;
  445.  
  446.     tapeCmd.mt_op = MTWEOF;
  447.     tapeCmd.mt_count = count;
  448.  
  449.     status = ioctl(volStream, MTIOCTOP, (char *)&tapeCmd);
  450.  
  451.     if (status == 0) {
  452.     return T_SUCCESS;
  453.     } else {
  454.     syserr = errno;
  455.     return T_IOFAILED;
  456.     }
  457. }
  458.  
  459.  
  460.  
  461. /*
  462.  *----------------------------------------------------------------------
  463.  *
  464.  * Dev_GetVolStatus --
  465.  *
  466.  *    Inquire into state of volume device
  467.  *
  468.  * Results:
  469.  *    return code
  470.  *
  471.  * Side effects:
  472.  *    None.
  473.  *
  474.  *----------------------------------------------------------------------
  475.  */
  476.  
  477. int
  478. Dev_GetVolStatus(volStream, volStatusPtr)
  479.     int volStream;            /* volume descriptor */
  480.     VolStatus *volStatusPtr;  /* receiving structure */
  481. {
  482.  
  483.     volStatusPtr->position = -1;
  484.     return T_SUCCESS;
  485. }
  486.  
  487. /*
  488.  *----------------------------------------------------------------------
  489.  *
  490.  * Dev_DisplayMsg --
  491.  *
  492.  *    Display message on jukebox screen
  493.  *
  494.  * Results:
  495.  *    return code
  496.  *
  497.  * Side effects:
  498.  *    Changes display on robot front panel.
  499.  *
  500.  * Note:
  501.  *      Message is silently truncated to EXB120_MAXMSG chars
  502.  *
  503.  *----------------------------------------------------------------------
  504.  */
  505.  
  506. int
  507. Dev_DisplayMsg(robotStream, msg, msgStyle)
  508.     int robotStream;          /* volume descriptor */
  509.     char *msg;                /* Message text */
  510.     int msgStyle;             /* 0==Steady, 1==flash, 2==scroll */
  511. {
  512.     robot_params robotCmd;
  513.  
  514.     strncpy(robotCmd.message, msg, EXB120_MAXMSG);
  515.     robotCmd.displayType = msgStyle;
  516.  
  517.     if (ioctl(robotStream, EXBJBOX_DISPLAY, (char *) &robotCmd) < 0) {
  518.         syserr = errno;
  519.     return T_FAILURE;
  520.     }
  521.     return T_SUCCESS;
  522.  
  523. }
  524.  
  525.  
  526. /*
  527.  *----------------------------------------------------------------------
  528.  *
  529.  * Dev_OpenDoor --
  530.  *
  531.  *    Open (or at least unlock) the jukebox door.
  532.  *
  533.  * Results:
  534.  *    return code
  535.  *
  536.  * Side effects:
  537.  *    None.
  538.  *
  539.  *----------------------------------------------------------------------
  540.  */
  541.  
  542. int
  543. Dev_OpenDoor(robotStream)
  544.     int robotStream;          /* robot descriptor */
  545.     return T_SUCCESS;
  546. }
  547.  
  548.  
  549. /*
  550.  *----------------------------------------------------------------------
  551.  *
  552.  * Dev_RemoveVolume --
  553.  *
  554.  *    Open (or at least unlock) the jukebox door.
  555.  *
  556.  * Results:
  557.  *    return code
  558.  *
  559.  * Side effects:
  560.  *    Kicks a volume out of archive.
  561.  *
  562.  *----------------------------------------------------------------------
  563.  */
  564.  
  565. int
  566. Dev_RemoveVolume(robotStream, src)
  567.     int robotStream;          /* robot descriptor */
  568.     int src;                  /* src slot location */
  569.     robot_params robotCmd;
  570.     
  571.     robotCmd.sourceAddr = src;
  572.     robotCmd.destAddr = 120; /* slot id of entry/exit port */
  573.  
  574.     if (ioctl(robotStream, SCSI_MOVE_MEDIUM, (char *) &robotCmd) < 0) {
  575.     fprintf(stderr, "Couldn't remove volume: errno %d", errno);
  576.     return T_FAILURE;
  577.     } else {
  578.     return T_SUCCESS;
  579.     }
  580.  
  581. }
  582.  
  583.  
  584. /*
  585.  *----------------------------------------------------------------------
  586.  *
  587.  * Dev_InsertVolume --
  588.  *
  589.  *    Open (or at least unlock) the jukebox door.
  590.  *
  591.  * Results:
  592.  *    return code
  593.  *
  594.  * Side effects:
  595.  *    Pull in a new volume.
  596.  *
  597.  *----------------------------------------------------------------------
  598.  */
  599.  
  600. int
  601. Dev_InsertVolume(robotStream, dest)
  602.     int robotStream;          /* robot descriptor */
  603.     int dest;                 /* destination slot location */
  604.     robot_params robotCmd;
  605.     
  606.     robotCmd.sourceAddr = 120; /* slot id of entry/exit port */
  607.     robotCmd.destAddr = dest;
  608.  
  609.     if (ioctl(robotStream, SCSI_MOVE_MEDIUM, (char *) &robotCmd) < 0) {
  610.     fprintf(stderr, "Couldn't insert volume: errno %d", errno);
  611.     return T_FAILURE;
  612.     } else {
  613.     return T_SUCCESS;
  614.     }
  615. }
  616.  
  617.  
  618. /*
  619.  *----------------------------------------------------------------------
  620.  *
  621.  * Dev_BuildVolList --
  622.  *
  623.  *    Build a list of jukebox's contents
  624.  *
  625.  * Results:
  626.  *    return code
  627.  *
  628.  * Side effects:
  629.  *    none.
  630.  *
  631.  *----------------------------------------------------------------------
  632.  */
  633.  
  634. int
  635. Dev_BuildVolList(robotStream, listPtr, cntPtr)
  636.     int robotStream;          /* robot descriptor */
  637.     VolConfig *listPtr;       /* space for volume info */
  638.     int *cntPtr;              /* size of list */
  639.     int i;
  640.     int cnt = 0;
  641.     int maxBin = EXB120_MAXBIN+1;
  642.     int retCode = T_SUCCESS;
  643.     char label[T_MAXLABELLEN];
  644.     
  645.     if (*cntPtr < maxBin) {
  646.     syserr = ENOSPC;
  647.     *cntPtr = EXB120_MAXBIN+1;
  648.     return T_FAILURE;
  649.     }
  650.  
  651.     for (i=0; i<maxBin; i++) {
  652.     if ((retCode=Dev_ReadVolLabel(robotStream, i, label)) != T_SUCCESS) {
  653.         *cntPtr = 0;
  654.         return retCode;
  655.     }
  656.     listPtr->volId = i;
  657.     listPtr->location = i;
  658.     strcpy(listPtr->volLabel, label);
  659.     listPtr++;
  660.     cnt++;
  661.     }
  662.  
  663.     *cntPtr = cnt;
  664.     return T_SUCCESS;
  665.  
  666. }
  667.  
  668.